<?php

declare(strict_types=1);

namespace app\controller\user;

use app\BaseController;
use app\model\User;
use app\service\factory\ResponseFactory;
use app\service\notify\UserNotificationService;
use InvalidArgumentException;
use think\Response;
use Throwable;

class Notification extends BaseController
{
    public function summary(UserNotificationService $service): Response
    {
        $user = $this->resolveUser();
        if (!$user) {
            return json(ResponseFactory::error('用户不存在', 404));
        }

        try {
            $data = $service->summary($user);
            return json(ResponseFactory::success($data));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function personal(UserNotificationService $service): Response
    {
        $user = $this->resolveUser();
        if (!$user) {
            return json(ResponseFactory::error('用户不存在', 404));
        }

        $page = max(1, (int) $this->request->param('page', 1));
        $pageSize = (int) $this->request->param('page_size', 10);
        $pageSize = $pageSize > 0 ? min($pageSize, 50) : 10;

        try {
            $data = $service->paginatePersonal($user, $page, $pageSize);
            return json(ResponseFactory::success($data));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function group(UserNotificationService $service): Response
    {
        $user = $this->resolveUser();
        if (!$user) {
            return json(ResponseFactory::error('用户不存在', 404));
        }

        $page = max(1, (int) $this->request->param('page', 1));
        $pageSize = (int) $this->request->param('page_size', 10);
        $pageSize = $pageSize > 0 ? min($pageSize, 50) : 10;

        try {
            $data = $service->paginateGroup($user, $page, $pageSize);
            return json(ResponseFactory::success($data));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function all(UserNotificationService $service): Response
    {
        $user = $this->resolveUser();
        if (!$user) {
            return json(ResponseFactory::error('用户不存在', 404));
        }

        $page = max(1, (int) $this->request->param('page', 1));
        $pageSize = (int) $this->request->param('page_size', 10);
        $pageSize = $pageSize > 0 ? min($pageSize, 50) : 10;

        try {
            $data = $service->paginateAll($user, $page, $pageSize);
            return json(ResponseFactory::success($data));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function markRead(UserNotificationService $service): Response
    {
        $user = $this->resolveUser();
        if (!$user) {
            return json(ResponseFactory::error('用户不存在', 404));
        }

        $payload = $this->request->only(['message_id', 'recipient_id'], $this->request->method());
        $messageId = isset($payload['message_id']) ? (int) $payload['message_id'] : 0;
        $recipientId = isset($payload['recipient_id']) ? (int) $payload['recipient_id'] : 0;

        if ($messageId <= 0 || $recipientId <= 0) {
            return json(ResponseFactory::error('参数不正确', 422));
        }

        try {
            $data = $service->markAsRead($user, $messageId, $recipientId);
            return json(ResponseFactory::success($data, '通知已标记为已读'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    private function resolveUser(): ?User
    {
        $userId = (int) ($this->request->user_id ?? 0);
        if ($userId <= 0) {
            return null;
        }

        return User::find($userId);
    }
}
